package com.xhz.cas.handler;

import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.xhz.cas.model.entity.SsoAccount;
import com.xhz.cas.model.service.SsoAccountService;
import com.xhz.cas.tools.PasswordEncryptUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apereo.cas.authentication.*;
import org.apereo.cas.authentication.exceptions.AccountDisabledException;
import org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;

import javax.security.auth.login.AccountLockedException;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.CredentialExpiredException;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * shiro验证器
 *
 * @author huangcb on 2020/4/18
 */
public class ShiroAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {

    @Autowired
    @Qualifier(value = "ssoAccountServiceImpl")
    private SsoAccountService ssoAccountService;

    public ShiroAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
        super(name, servicesManager, principalFactory, order);
    }

    /**
     * 认证处理程序执行结果
     *
     * @param credential       凭证
     * @param originalPassword 原始密码
     * @return
     * @throws GeneralSecurityException
     * @throws PreventedException
     */
    @Override
    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword) throws GeneralSecurityException, PreventedException {
        String username = credential.getUsername();
        String password = credential.getPassword();
        SsoAccount account = ssoAccountService.getByLoginInfo(username);
        final String encryptPassword = PasswordEncryptUtil.encrypt(password, username);
        if (!encryptPassword.equals(account.getPassword())) {//密码错误
            throw new FailedLoginException();
        };
        if(account.getExpired() != 0){
            throw new CredentialExpiredException();
        };
        if(account.getDisabled() !=0 ){
            throw new AccountDisabledException();
        };
        Map<String, Object> resultMap = BeanUtils.beanToMap(account);
        resultMap.remove("password");
        return createHandlerResult(credential, this.principalFactory.createPrincipal(credential.getUsername(), resultMap), new ArrayList<>(0));
    }


}
